/*
 * main.cpp
 *
 *  Created on: Feb 2, 2010
 *      Author: Jamie LaPointe
 *
 *  Notes: Very simple Hello World thread example that displays how to send arguments
 *  from the main thread to the newly created threads while allowing it to be thread
 *  safe... you will note that std::cout is NOT thread safe by running this example multiple
 *  times and seeing some strange output on some of the runs.
 */

#include <pthread.h>
#include <iostream>

#define NUM_THREADS 5

struct PrintHelloArg
{
   unsigned int threadId;
};

void * printHello(void * arg)
{
   PrintHelloArg * myArg = (PrintHelloArg *) arg;
   std::cout << "Hello World!  It's me, thread #" << myArg->threadId
         << std::endl;
   pthread_exit(NULL);
   return NULL;
}

int main()
{
   pthread_t threads[NUM_THREADS];
   int returnCode = 0;
   int threadIndex = 0;

   /*
    * This must be created outside  the loop (so that it lives as long as the main program and
    * can be accessed by the new thread);
    * Must create an array so that separate arg variables are created for each thread we plan
    * on creating; otherwise we would be sending a shared memory variable whose value could
    * be overwritten by the main thread before being used by the new thread.
    */
   PrintHelloArg arg[NUM_THREADS];

   for (threadIndex = 0; threadIndex < NUM_THREADS; ++threadIndex)
   {
      arg[threadIndex].threadId = threadIndex;
      std::cout << "In main: creating thread #" << arg[threadIndex].threadId
            << std::endl;
      returnCode = pthread_create(&threads[threadIndex], NULL, printHello,
            (void *) (&(arg[threadIndex])));
      if (returnCode != 0)
      {
         std::cerr << "ERROR: return code from pthread_create = " << returnCode
               << std::endl;
         return -1;
      }
   }

   pthread_exit(NULL);
   return 0;
}
